using System.Security.Principal;
using System.Web;
using WebMatrix.WebData;

namespace Quintsys.Core.Services
{
    public interface IWebSecurity
    {
        /// <summary>
        /// Logs the user in.
        /// </summary>
        /// 
        /// <returns>
        /// true if the user was logged in; otherwise, false.
        /// </returns>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password.</param>
        /// <param name="persistCookie">(Optional) true to specify that the authentication token in the cookie should be persisted beyond the current session; otherwise false. The default is false.</param>
        bool Login(string userName, string password, bool persistCookie = false);

        /// <summary>
        /// Logs the user out.
        /// </summary>
        void Logout();

        /// <summary>
        /// Creates a new user profile entry and a new membership account.
        /// </summary>
        /// 
        /// <returns>
        /// A token that can be sent to the user to confirm the user account.
        /// </returns>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password for the user.</param>
        /// <param name="propertyValues">(Optional) A dictionary that contains additional user attributes. The default is null.</param>
        /// <param name="requireConfirmationToken">(Optional) true to specify that the user account must be confirmed; otherwise, false. The default is false.</param>
        string CreateUserAndAccount(string userName, string password, object propertyValues = null,
                                    bool requireConfirmationToken = false);

        /// <summary>
        /// Returns the ID for a user based on the specified user name.
        /// </summary>
        /// 
        /// <returns>
        /// The user ID.
        /// </returns>
        /// <param name="userName">The user name.</param>
        int GetUserId(string userName);

        /// <summary>
        /// Changes the password for the specified user.
        /// </summary>
        /// 
        /// <returns>
        /// true if the password is successfully changed; otherwise, false.
        /// </returns>
        /// <param name="userName">The user name.</param>
        /// <param name="currentPassword">The current password for the user.</param>
        /// <param name="newPassword">The new password.</param>
        bool ChangePassword(string userName, string currentPassword, string newPassword);

        /// <summary>
        /// Creates a new membership account using the specified user name and password and optionally lets you specify that the user must explicitly confirm the account.
        /// </summary>
        /// 
        /// <returns>
        /// A token that can be sent to the user to confirm the account.
        /// </returns>
        /// <param name="userName">The user name.</param><param name="password">The password.</param>
        /// <param name="requireConfirmationToken">(Optional) true to specify that the account must be confirmed by using the token return value; otherwise, false. The default is false. </param>
        string CreateAccount(string userName, string password, bool requireConfirmationToken = false);

        /// <summary>
        /// Gets the current user.
        /// </summary>
        /// <value>
        /// The current user.
        /// </value>
        IPrincipal CurrentUser { get; }
    }

    public class WebSecurityWrapper : IWebSecurity
    {
        /// <summary>
        /// Logs the user in.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password.</param>
        /// <param name="persistCookie">(Optional) true to specify that the authentication token in the cookie should be persisted beyond the current session; otherwise false. The default is false.</param>
        /// <returns>
        /// true if the user was logged in; otherwise, false.
        /// </returns>
        public bool Login(string userName, string password, bool persistCookie = false)
        {
            return WebSecurity.Login(userName, password, persistCookie);
        }

        /// <summary>
        /// Logs the user out.
        /// </summary>
        public void Logout()
        {
            WebSecurity.Logout();
        }

        /// <summary>
        /// Creates a new user profile entry and a new membership account.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password for the user.</param>
        /// <param name="propertyValues">(Optional) A dictionary that contains additional user attributes. The default is null.</param>
        /// <param name="requireConfirmationToken">(Optional) true to specify that the user account must be confirmed; otherwise, false. The default is false.</param>
        /// <returns>
        /// A token that can be sent to the user to confirm the user account.
        /// </returns>
        public string CreateUserAndAccount(string userName, string password, object propertyValues = null,
                                           bool requireConfirmationToken = false)
        {
            return WebSecurity.CreateUserAndAccount(userName, password, propertyValues, requireConfirmationToken);
        }

        /// <summary>
        /// Returns the ID for a user based on the specified user name.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <returns>
        /// The user ID.
        /// </returns>
        public int GetUserId(string userName)
        {
            return WebSecurity.GetUserId(userName);
        }

        /// <summary>
        /// Changes the password for the specified user.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="currentPassword">The current password for the user.</param>
        /// <param name="newPassword">The new password.</param>
        /// <returns>
        /// true if the password is successfully changed; otherwise, false.
        /// </returns>
        public bool ChangePassword(string userName, string currentPassword, string newPassword)
        {
            return WebSecurity.ChangePassword(userName, currentPassword, newPassword);
        }

        /// <summary>
        /// Creates a new membership account using the specified user name and password and optionally lets you specify that the user must explicitly confirm the account.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <param name="password">The password.</param>
        /// <param name="requireConfirmationToken">(Optional) true to specify that the account must be confirmed by using the token return value; otherwise, false. The default is false.</param>
        /// <returns>
        /// A token that can be sent to the user to confirm the account.
        /// </returns>
        public string CreateAccount(string userName, string password, bool requireConfirmationToken = false)
        {
            return WebSecurity.CreateAccount(userName, password, requireConfirmationToken);
        }

        /// <summary>
        /// Gets the current user.
        /// </summary>
        /// <value>
        /// The current user.
        /// </value>
        public IPrincipal CurrentUser
        {
            get { return HttpContext.Current.User; }
        }
    }
}